<?php

require_once 'IObject.php';
require_once 'Dump.php';

/**
 * @param mixed $object
 * @return Object
 */
function o () {
	$argv = func_get_args();
	$argc = func_num_args();
	if ($argc > 1) {
		return new Map ($argv);
	} else if (!$argc) {
		throw new OOException("Wrong parametr count");
	} else {
		$a = $argv[0];
		return is_array($a)   ? new Map ($a)    : (
		       is_string($a)  ? new String ($a) : (
		       is_numeric($a) ? new Number ($a) : (
		                        $a )));
	}
}

function dump () {
	foreach (func_get_args() as $arg) {
		echo new Dump($arg);
	}
}

class OOException extends Exception {}

class Object implements IObject {
	/**
	 * @var mixed
	 */
	protected $atom;

	public function __construct ($atom) {
		$this->atom = $atom;
	}

	/**
	 * @return mixed
	 */
	public function getAtom () {
		return $this->atom;
	}

	/**
	 * @param Closure $func
	 * @return bool
	 */
	public function match ($func) {
		return (bool) $func ($this);
	}

	/**
	 * @return Object
	 */
	public function copy () {
		$self = get_class($this);
		return new $self($this);
	}

	/**
	 * @return void
	 */
	public function dump () {
		echo new Dump ($this);
		return $this;
	}

	/**
	 * @param mixed $var
	 * @return bool
	 */
	protected function isClosure ($var) {
		return (is_object($var) and is_callable($var));
	}

	/**
	 * @param mixed $obj
	 * @return int|float
	 */
	protected function toNum ($obj) {
		return ($obj instanceof Number) ?
			$obj->getAtom() : $obj + 0;
	}

	/**
	 * @param mixed $elem
	 * @return Object|mixed
	 */
	protected function toObject ($elem) {
		return
			is_array   ($elem) ? new Map    ($elem) : (
			is_string  ($elem) ? new String ($elem) : (
			is_numeric ($elem) ? new Number ($elem) : $elem
			));
	}

	/**
	 * @param mixed $obj
	 * @return mixed
	 */
	protected function toAtom ($obj) {
		return ($obj instanceof Object) ?
			$obj->getAtom() : $obj;
	}

	/**
	 * @return bool
	 */
	protected function isMb () {
    	return Str::isMultyByte();
	}
	
	/**
	 * @param callable $func
	 * @return Object
	 */
	protected function func ($func) {
		$this->atom = $func($this->atom);
		return $this;
	}

	/**
	 * @return bool
	 */
	public function isEmpty () {
		return empty($this->atom);
	}
}